﻿@page "/account/manage/generate-recovery-codes"

@using Microsoft.AspNetCore.Identity

@inject UserManager<AdminUser> UserManager
@inject ILogger<GenerateRecoveryCodes> Logger

<LayoutPageTitle>Generate two-factor authentication (2FA) recovery codes</LayoutPageTitle>

@if (_recoveryCodes is not null)
{
    <ShowRecoveryCodes RecoveryCodes="_recoveryCodes.ToArray()"/>
}
else
{
    <h3 class="text-xl font-bold mb-4">Generate two-factor authentication (2FA) recovery codes</h3>
    <div class="bg-primary-100 border-l-4 border-primary-500 text-primary-700 p-4 mb-4" role="alert">
        <p class="mb-2">
            <svg class="inline w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path>
            </svg>
            <strong>Put these codes in a safe place.</strong>
        </p>
        <p class="mb-2">
            If you lose your device and don't have the recovery codes you will lose access to your account.
        </p>
        <p>
            Generating new recovery codes does not change the keys used in authenticator apps. If you wish to change the key
            used in an authenticator app you should <a href="account/manage/reset-authenticator" class="text-primary-600 hover:text-primary-800 underline">reset your authenticator keys.</a>
        </p>
    </div>
    <div>
        <button class="bg-primary-600 hover:bg-primary-700 text-white font-bold py-2 px-4 rounded" @onclick="GenerateCodes" type="submit">Generate Recovery Codes</button>
    </div>
}

@code {
    private IEnumerable<string>? _recoveryCodes;

    /// <inheritdoc />
    protected override async Task OnInitializedAsync()
    {
        await base.OnInitializedAsync();

        var user = await UserManager.FindByIdAsync(UserService.User().Id);
        if (user == null)
        {
            throw new InvalidOperationException("User not found.");
        }

        var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user);
        if (!isTwoFactorEnabled)
        {
            throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled.");
        }
    }

    private async Task GenerateCodes()
    {
        var user = await UserManager.FindByIdAsync(UserService.User().Id);
        if (user == null)
        {
            throw new InvalidOperationException("User not found.");
        }

        _recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10);
        GlobalNotificationService.AddSuccessMessage("You have generated new recovery codes.");

        Logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", UserService.User().Id);
    }

}
